package com.hilton.tigershark.view;

import java.util.Date;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.net.http.SslCertificate;
import android.net.http.SslError;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.SslErrorHandler;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.hilton.tigershark.R;
import com.hilton.tigershark.TabControl;

public class SSLDialogManager {
    private final Activity mActivity;
    private final TabControl mTabControl;
    private LayoutInflater mLayoutInflater;
    
    public SSLDialogManager(Activity a, TabControl tc) {
        mActivity = a;
        mTabControl = tc;
        mLayoutInflater = LayoutInflater.from(mActivity);
    }

    private AlertDialog mWarningsDialog;
    private AlertDialog mCertificateDialog;
    public boolean hasDialogShowing() {
        return warningsShowing() || certificateShowing();
    }
    
    public void reshowDialogs() {
        if (warningsShowing()) {
            mWarningsDialog.dismiss();
            reshowSSLDialog();
        }
        if (certificateShowing()) {
            mCertificateDialog.dismiss();
            viewCertificate();
        }
    }
    
    private void reshowSSLDialog() {
        showSSLCertificateDialog(mErrorHandler, mError);
    }

    private boolean warningsShowing() {
        return mWarningsDialog != null && mWarningsDialog.isShowing();
    }

    private boolean certificateShowing() {
        return mCertificateDialog != null && mCertificateDialog.isShowing();
    }

    private SslErrorHandler mErrorHandler;
    private SslError mError;
    private void init(SslErrorHandler handler, SslError error) {
        mErrorHandler = handler;
        mError = error;
    }
    public void showSSLCertificateDialog(final SslErrorHandler handler, final SslError error) {
        init(handler, error);
        final View warningsView = createWarningsView(error);
        mWarningsDialog = showWarningsDialog(warningsView);
    }

    private AlertDialog showWarningsDialog(View warningsView) {
        AlertDialog dialog = new AlertDialog.Builder(mActivity)
        .setTitle(R.string.security_warning)
        .setIcon(android.R.drawable.ic_dialog_alert)
        .setView(warningsView)
        .setPositiveButton(R.string.ssl_continue,
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    mErrorHandler.proceed();
                }
            })
        .setNeutralButton(R.string.view_certificate,
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    viewCertificate();
                }
            })
        .setNegativeButton(R.string.cancel,
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    declineWarning(mErrorHandler);
                }
            })
        .setOnCancelListener(
            new DialogInterface.OnCancelListener() {
                public void onCancel(DialogInterface dialog) {
                    declineWarning(mErrorHandler);
                }
            })
        .show();
        return dialog;
    }
    
    private void declineWarning(final SslErrorHandler handler) {
        handler.cancel();
        mTabControl.resetTitleAndRevertLockIcon();
    }
    
    private View createWarningsView(final SslError error) {
        final View warningsView = mLayoutInflater.inflate(R.layout.ssl_warnings, null);
        fillWarnings(warningsView);
        return warningsView;
    }
    
    private void fillWarnings(final View certificateView) {
        if (mError.hasError(SslError.SSL_UNTRUSTED)) {
            setWarningText(certificateView, R.string.ssl_untrusted);
        }
        
        if (mError.hasError(SslError.SSL_IDMISMATCH)) {
            setWarningText(certificateView, R.string.ssl_mismatch);
        }
        
        if (mError.hasError(SslError.SSL_EXPIRED)) {
            setWarningText(certificateView, R.string.ssl_expired);
        }
        
        if (mError.hasError(SslError.SSL_NOTYETVALID)) {
            setWarningText(certificateView, R.string.ssl_not_yet_valid);
        }
    }
    
    private void setWarningText(View certificateView, int textId) {
        final LinearLayout placeholder =
            (LinearLayout) certificateView.findViewById(R.id.placeholder);
        final View v = mLayoutInflater.inflate(R.layout.ssl_warning, placeholder);
        setTextViewText(v, R.id.warning, mActivity.getString(textId));
    }

    private void viewCertificate() {
        final View certificateView = mLayoutInflater.inflate(R.layout.ssl_certificate, null);
        fillWarnings(certificateView);
        fillCertificateInfo(certificateView, mError.getCertificate());
        mCertificateDialog = showCertificateDialog(certificateView);
    }
    
    private AlertDialog showCertificateDialog(View certificateView) {
        AlertDialog dialog = new AlertDialog.Builder(mActivity)
        .setTitle(R.string.ssl_certificate)
        .setIcon(R.drawable.ic_dialog_browser_certificate_partially_secure)
        .setView(certificateView)
        .setPositiveButton(R.string.ssl_continue, new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                mErrorHandler.proceed();
            }
        })
        .setNegativeButton(R.string.ok, null)
        .setOnCancelListener(new OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                declineWarning(mErrorHandler);
            }
        })
        .show();
        return dialog;
    }
    
    private View fillCertificateInfo(View certificateView, SslCertificate certificate) {
        // issued to:
        SslCertificate.DName issuedTo = certificate.getIssuedTo();
        if (issuedTo != null) {
            setTextViewText(certificateView, R.id.to_common, issuedTo.getCName());
            setTextViewText(certificateView, R.id.to_org, issuedTo.getOName());
            setTextViewText(certificateView, R.id.to_org_unit, issuedTo.getUName());
        }

        // issued by:
        SslCertificate.DName issuedBy = certificate.getIssuedBy();
        if (issuedBy != null) {
            setTextViewText(certificateView, R.id.by_common, issuedBy.getDName());
            setTextViewText(certificateView, R.id.by_org, issuedBy.getOName());
            setTextViewText(certificateView, R.id.by_org_unit, issuedBy.getUName());
        }

        // issued on:
        setTextViewText(certificateView, R.id.issued_on, localDateFormat(certificate.getValidNotBeforeDate()));

        // expires on:
        setTextViewText(certificateView, R.id.expires_on, localDateFormat(certificate.getValidNotAfterDate()));

        return certificateView;
    }

    private void setTextViewText(final View view, int id, String text) {
        ((TextView) view.findViewById(id)).setText(text);
    }

    private String localDateFormat(Date date) {
        if (date == null) {
            return "";
        }
        String formattedDate = DateFormat.getDateFormat(mActivity).format(date);
        return formattedDate == null ? "" : formattedDate;
    }
}
